package com.fingard.dsp.bank.directbank.jrtt01;

import com.alibaba.fastjson.JSON;
import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextWriter;

import java.security.MessageDigest;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by F on 2018/10/10.
 * 公共方法
 */
public class JRTT01Base extends DirectBase {

    private static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE BANKREQSEQID=?";

    protected String flag = "SET:";//获取元素接口标识
    protected String intervalFlag = "\\|_\\|";//返回元素之间的分隔符
    //protected String enumFlag="-\\|\\|-";//返回枚举分隔符
    protected String reqFlag = "ZZ";//请求流水号标识符

    /**
     * 编码
     *
     * @return
     */
    protected String getCharset() {
        return getBankConfig().getCharset("UTF-8");
    }

    /**
     * 唯一流水号，银行不做唯一校验
     *
     * @return
     */
    protected String getQryTransID() {
        return Format.DateTime17Format.format(new Date());
    }

    /**
     * 请求报文头
     *
     * @param xmlWriter
     * @param p_bankHeader
     * @throws Exception
     */
    protected void writeCommonHeader(XmlTextWriter xmlWriter, JRTT01Header p_bankHeader) throws Exception {
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
        xmlWriter.writeStartElement("Document");
        xmlWriter.writeStartElement("Request");
        xmlWriter.writeStartElement("GrpHdr");
        xmlWriter.writeElementStringWithoutTransfer("RequestType", p_bankHeader.requestType);//交易代码
        xmlWriter.writeElementStringWithoutTransfer("MsgId", p_bankHeader.msgId);//唯一流水
        Date today = new Date();
        String times = Format.Date10Format.format(today) + "T" + Format.Time8Format.format(today) + "+08:00";
        xmlWriter.writeElementStringWithoutTransfer("CreDtTm", times);//时间戳
    }

    /**
     * 发送报文至银行
     *
     * @param p_reqStr 请求报文
     * @return
     * @throws Exception
     */
    protected String[] sendToBank(String p_reqStr, String code) throws Exception {
        String[] retStr = new String[]{"", ""};
        String serverURL = bankFront.serverURL + "/" + code + "/api/services";
        WriteBankLogLn("1.提交银行的地址：" + serverURL);
        WriteBankLogStep2(p_reqStr);
        WebRequest tmpWebRequest = new WebRequest(serverURL);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Content-Type", "application/xml");
        tmpWebRequest.setRequestProperty("Accept-language", "zh_CN");
        byte[] tmpToWriteBytes = p_reqStr.getBytes(getCharset());
        retStr = tmpWebRequest.upload(tmpToWriteBytes, getCharset());
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }


    /**
     * 字段属性映射
     *
     * @param reqiured
     * @return
     */
    protected String typeConversion(String reqiured) {
        if (!"".equals(reqiured) && reqiured != null) {
            if ("mandatory".equals(reqiured)) {
                reqiured = "0";//必传
            } else if ("supress".equals(reqiured)) {
                reqiured = "1";//不输
            } else if ("optional".equals(reqiured)) {
                reqiured = "2";//选输
            }
        }
        return reqiured;
    }

    /**
     * 获取付方金额和付方币种
     *
     * @param name
     * @param value
     * @param fliedNum
     * @return
     */
    protected String[] getAmountAndCcy(String name, String value, String fliedNum) {
        String[] dspResult = new String[]{"", ""};
        int num = Integer.parseInt(fliedNum) + 1;//总字段数+1
        String[] nameArr = name.split(intervalFlag, -1);//保留分隔符后面存在的空值
        String[] valueArr = value.split(intervalFlag, -1);//保留分隔符后面存在的空值
        //校验字段是否一致
        if (num != nameArr.length || num != valueArr.length) {
            dspResult[0] = "";
            dspResult[1] = "";
            return dspResult;
        }
        if (StringHelper.isNullOrEmpty(nameArr[nameArr.length - 1]) && StringHelper.isNullOrEmpty(valueArr[valueArr.length - 1])) {
            num = num - 1;
        }
        for (int i = 0; i < num; i++) {
            if ("PayAmount".equals(nameArr[i].trim())) {//
                dspResult[0] = valueArr[i].trim();//付款金额
            }
            if ("PayCurrency".equals(nameArr[i].trim())) {//
                dspResult[1] = valueArr[i].trim();//付款币种
            }
        }
        return dspResult;
    }

    /**
     * 拼接字段串
     *
     * @param xmlTextWriter
     * @param name
     * @param value
     * @return
     */
    protected String[] xmlTextWriterBody(XmlTextWriter xmlTextWriter, String name, String value, String fliedNum) {
        String[] dspResult = new String[]{"0", ""};
        int num = Integer.parseInt(fliedNum) + 1;//总字段数+1
        String[] nameArr = name.split(intervalFlag, -1);//保留分隔符后面存在的空值
        String[] valueArr = value.split(intervalFlag, -1);//保留分隔符后面存在的空值
        //校验字段是否一致
        if (num != nameArr.length || num != valueArr.length) {
            dspResult[0] = "-1";
            dspResult[1] = "DetailRecord总数据与RecordNum不一致";
            return dspResult;
        }
        if (StringHelper.isNullOrEmpty(nameArr[nameArr.length - 1]) && StringHelper.isNullOrEmpty(valueArr[valueArr.length - 1])) {
            num = num - 1;
        }
        //获取付款金额、付款币种
        String payAmount = "";
        String payCurrency = "";
        for (int i = 0; i < num; i++) {
            if ("PayAmount".equals(nameArr[i].trim())) {//
                payAmount = valueArr[i].trim();
            }
            if ("PayCurrency".equals(nameArr[i].trim())) {//
                payCurrency = valueArr[i].trim();
            }
        }
        //拼接付款请求字段
        try {
            String payAmountOk = checkPayAmount2(payAmount, payCurrency);
            if (StringHelper.hasAnyChar(payAmountOk)) {
                //开始处理字段
                for (int i = 0; i < num; i++) {
                    //TemplateName字段，取ats请求的值
                    if ("TemplateName".equals(nameArr[i].trim())) {
                        continue;
                    }
                    xmlTextWriter.writeStartElement("Field");
                    if ("InboundPurpCode".equals(nameArr[i].trim())) {//
                        valueArr[i] = valueArr[i].trim().split("-\\|\\|-")[0];
                    }
                    if ("OutboundPurpCode".equals(nameArr[i].trim())) {//
                        valueArr[i] = valueArr[i].trim().split("-\\|\\|-")[0];
                    }
                    if ("PayAmount".equals(nameArr[i].trim())) {
                        valueArr[i] = payAmountOk;
                    }
                    xmlTextWriter.writeElementStringWithoutTransfer("Name", nameArr[i].trim());//字段名
                    xmlTextWriter.writeElementStringWithoutTransfer("Value", valueArr[i].trim());//字段值
                    xmlTextWriter.writeEndElement();
                }
            }
        } catch (Exception e) {
            dspResult[0] = "-1";
            dspResult[1] = e.getMessage();
            WriteBankLogLn(e.getMessage());
            return dspResult;
        }
        return dspResult;
    }

    /**
     * 获取付款流水号
     *
     * @param reqId
     * @param name
     * @param value
     * @param fliedNum
     * @return
     * @throws Exception
     */
    protected String getReqId(String reqId, String name, String value, String fliedNum) throws Exception {
        String reqBankId = reqFlag + reqId;//流水号
        int num = Integer.parseInt(fliedNum) + 1;//总字段数+1
        String[] nameArr = name.split(intervalFlag, -1);
        String[] valueArr = value.split(intervalFlag, -1);
        if (num == nameArr.length && num == valueArr.length) {
            String bankType = "";
            String methodName = "";
            String payCurrency = "";
            //获取值
            for (int i = 0; i < num - 1; i++) {
                if ("BankType".equals(nameArr[i].trim())) {
                    bankType = valueArr[i];//
                }
                if ("MethodName".equals(nameArr[i].trim())) {
                    methodName = valueArr[i];//
                }
                if ("PayCurrency".equals(nameArr[i].trim())) {
                    payCurrency = valueArr[i];//
                }
            }
            //校验
            if ("CITI".equals(bankType) && "WL".equals(methodName) && "RUB".equals(payCurrency)) {
                reqBankId = getReqIdFour();//俄罗斯取6位流水号且不为0
            }
            //
            //校验
            if ("CITI".equals(bankType) && "WL".equals(methodName) && "MXN".equals(payCurrency)) {
                reqBankId = getReqIdSix();//墨西哥取8位流水号
            }
        }
        //返回
        return reqBankId;
    }

    /**
     * 获取字符串中数字最大值
     *
     * @param content
     * @return
     */
    protected String getMaxLength(String content) {
        Pattern p = Pattern.compile("\\d+");
        Matcher matcher = p.matcher(content);
        List<Integer> numList = new ArrayList<Integer>();
        while (matcher.find()) {
            numList.add(Integer.parseInt(matcher.group()));
        }
        if (numList.isEmpty()) {
            return "";
        } else {
            return Collections.max(numList) + "";
        }
    }

    /**
     * 获取Request内容
     *
     * @param xmlTextWriter
     * @return
     */
    protected String getRequestXml(String xmlTextWriter) {
        //获取Request的内容
        String request = xmlTextWriter.substring(xmlTextWriter.indexOf("<Request>"), xmlTextWriter.indexOf("</Request>") + "</Request>".length());
        return request;
    }

    /**
     * 转化为全球UTC时间
     *
     * @param date
     * @param timeZone
     * @return
     */
    protected String getGlobalLocalDate(Date date, String timeZone) {
        SimpleDateFormat utcSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date2 = "";
        try {
            TimeZone zone = TimeZone.getTimeZone(timeZone.replace("UTC", "GMT"));
            utcSdf.setTimeZone(zone);
            date2 = Format.Date10Format.format(Format.Date10Format.parse(utcSdf.format(date)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date2;
    }

    /**
     * 6位唯一流水号
     *
     * @return
     */
    protected String getReqIdFour() throws Exception {
        Connection conn = FGBiz.getLocalDbConn();
        String code = "";//流水号
        try {
            while ("".equals(code)) {
                //生成六位位流水号
                code = radomFourReq();
                code = reqFlag + code;
                //查询本地数据库是否存在
                Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{code});
                if (selMap.size() > 0) {//流水号存在则重新生成
                    code = "";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.close();
        }
        return code;
    }

    /**
     * 8位不含0的唯一流水号
     *
     * @return
     */
    protected String getReqIdSix() throws Exception {
        Connection conn = FGBiz.getLocalDbConn();
        String code = "";//流水号
        try {
            while ("".equals(code)) {
                //生成八位流水号
                code = radomSixReq();
                code = reqFlag + code;
                //查询本地数据库是否存在
                Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{code});
                if (selMap.size() > 0) {//流水号存在则重新生成
                    code = "";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.close();
        }
        return code;
    }

    /**
     * 随机四位不含0的流水号
     *
     * @return
     */
    protected String radomFourReq() {
        String s = "qwertyuiopasdfghjklzxcvbnm";
        String sMax = s.toUpperCase();
        String num = "123456789";
        char[] chars = (sMax + num).toCharArray();
        Random rd = new Random();
        String code = "";
        for (int k = 0; k < 4; k++) {
            int index = rd.nextInt(chars.length);//随机获取数组长度作为索引
            code += chars[index];//循环添加到字符串后面
        }
        return code;
    }

    /**
     * 随机六位流水号
     *
     * @return
     */
    protected String radomSixReq() {
        String s = "qwertyuiopasdfghjklzxcvbnm";
        String sMax = s.toUpperCase();
        String num = "1234567890";
        char[] chars = (sMax + num).toCharArray();
        Random rd = new Random();
        String code = "";
        for (int k = 0; k < 6; k++) {
            int index = rd.nextInt(chars.length);//随机获取数组长度作为索引
            code += chars[index];//循环添加到字符串后面
        }
        return code;
    }

    /**
     * 校验金额是否符合付方币种要求
     *
     * @param payAmount
     */
    protected String checkPayAmount2(String payAmount, String payCurrency) throws Exception {
        //校验小数位是否支持此币种位
        if (StringHelper.hasAnyChar(payCurrency) && payCurrency.length() == 3 && StringHelper.hasAnyChar(payAmount)) {
            //如果金额含小数点：
            // 3、num<小数位：判断num位后的数字串是否都为0
            //      1、是：减少(小数位-num)个0；过
            //      2、否：提示错误 不过
            if (payAmount.contains(".")) {
                //获取小数点后的数字
                String amountFloat = payAmount.substring(payAmount.indexOf(".") + 1).trim();
                if (amountFloat.length() <= 2) {
                    int num = 0;
                    //判断付款币种是否特殊
                    String unCcyNum = getBankConfig().getMapValueByKey("ccySupportDcmMapping", payCurrency);
                    //不是特殊币种，根据标准小数位来处理
                    if (StringHelper.isNullOrEmpty(unCcyNum)) {
                        //获取付款币种支持小数位
                        Currency ccy = Currency.getInstance(payCurrency);
                        num = ccy.getDefaultFractionDigits();
                    } else {//是特殊币种，按配置的小数位来处理
                        num = Integer.parseInt(unCcyNum);
                    }
                    WriteBankLogLn("币种" + payCurrency + "支持小数位为" + num);
                    if (num < amountFloat.length()) {
                        if (Integer.parseInt(amountFloat.substring(num, amountFloat.length())) == 0) {
                            payAmount = payAmount.substring(0, payAmount.length() - (amountFloat.length() - num));
                            if (payAmount.substring(payAmount.length() - 1).equals(".")) {
                                payAmount = payAmount.replace(".", "");
                            }
                        } else {
                            throw new Exception("付款币种" + payCurrency + "所支持的小数位" + num + "对应的" +
                                    "付款金额" + payAmount + "的小数位不一致，请输入在支持范围内带小数的金额");
                        }
                    }
                } else {
                    throw new Exception("付款币种" + payCurrency + "对应的" +
                            "付款金额" + payAmount + "的小数位不能超过两位");
                }

            }
        } else {
            throw new Exception("付款币种" + payCurrency + "及付款金额" + payAmount + "存在格式有误");
        }
        return payAmount;
    }

    /**
     * 校验金额是否符合付方币种要求
     *
     * @param payAmount
     */
    protected String[] checkPayAmount(String payAmount, String payCurrency) {
        String[] result = new String[]{"", ""};
        //校验小数位是否支持此币种位
        if (StringHelper.hasAnyChar(payCurrency) && payCurrency.length() == 3 && StringHelper.hasAnyChar(payAmount)) {
            //获取付款币种支持小数位
            Currency ccy = Currency.getInstance(payCurrency);
            int num = ccy.getDefaultFractionDigits();
            WriteBankLogLn("币种" + payCurrency + "支持小数位为" + num);
            //如果金额不含小数点：num为几，则增加几位小数，过
            //如果金额含小数点：
            // 1、num=小数位；过；
            // 2、num>小数位: 增加(num-小数位)个0  过
            // 3、num<小数位：判断num位后的数字串是否都为0
            //      1、是：减少(小数位-num)个0；过
            //      2、否：提示错误 不过
            if (payAmount.contains(".")) {
                //获取小数点后的数字
                String amountFloat = payAmount.substring(payAmount.indexOf(".") + 1).trim();
                if (num == amountFloat.length()) {
                    result[0] = payAmount;
                } else if (num > amountFloat.length()) {
                    payAmount = addZero(payAmount, num - amountFloat.length());
                    result[0] = payAmount;
                } else {
                    if (Integer.parseInt(amountFloat.substring(num, amountFloat.length())) == 0) {
                        payAmount = payAmount.substring(0, payAmount.length() - (amountFloat.length() - num));
                        if (payAmount.substring(payAmount.length() - 1).equals(".")) {
                            payAmount = payAmount.replace(".", "");
                        }
                        result[0] = payAmount;
                    } else {
                        result[1] = "付款币种" + payCurrency + "所支持的小数位" + num + "对应的" +
                                "付款金额" + payAmount + "的小数位不一致，请输入在支持范围内带小数的金额";
                        payAmount = "";
                        result[0] = payAmount;
                    }
                }
            } else {
                if (num == 0) {
                    result[0] = payAmount;
                } else {
                    payAmount = addZero(payAmount, num);
                    result[0] = payAmount;
                }
            }
        } else {
            result[1] = "付款币种" + payCurrency + "及付款金额" + payAmount + "存在格式有误";
        }
        return result;
    }

    /**
     * 小数位增加0
     *
     * @param payAmount
     * @param num
     * @return
     */
    protected String addZero(String payAmount, int num) {
        if (!payAmount.contains(".")) {
            payAmount = payAmount + ".";
        }
        for (int i = 0; i < num; i++) {
            payAmount += "0";
        }
        return payAmount;
    }

    /**
     * 签名
     *
     * @param paramXml    请求报文
     * @param xmlNodeName 节点名
     * @param secret      密码
     * @param encode      编码
     * @return
     */
    protected String signXml(String paramXml, String xmlNodeName, String secret, String encode) {
        WriteBankLogLn("签名开始" + paramXml);
        int startIndex = paramXml.indexOf("<" + xmlNodeName + ">");
        int endIndex = paramXml.lastIndexOf("</" + xmlNodeName + ">") + xmlNodeName.length() + 3;
        String signContent = paramXml.substring(startIndex, endIndex) + secret;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            return byte2hexString(md.digest(signContent.getBytes(encode)));
        } catch (Exception ex) {
            throw new RuntimeException("sign error !", ex);
        }
    }

    /**
     * 验签
     *
     * @param signature
     * @param paramXml
     * @param xmlNodeName
     * @param secret
     * @param encode
     * @return
     */
    protected boolean verifyXmlSign(String signature, String paramXml, String xmlNodeName, String secret, String encode) {
        WriteBankLogLn("验签开始" + paramXml);
        String newSign = signXml(paramXml, xmlNodeName, secret, encode);
        if (newSign.equals(signature)) {
            return true;
        }
        return false;
    }

    private String byte2hexString(byte[] b) {
        StringBuilder sb = new StringBuilder("");
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            if (stmp.length() == 1) {
                sb.append("0").append(stmp);
            } else {
                sb.append(stmp);
            }
        }
        return sb.toString();
    }

    /**
     * 解析86字段
     *
     * @param str86
     * @param CdFlag
     * @return
     */
    protected Map<String, String> resolveTag86(String str86, String CdFlag, boolean qryHisTrans) {
        Map<String, String> tag86Map = new HashMap<String, String>();
        if (!StringHelper.isNullOrEmpty(str86)) {
            str86 = str86.substring(1).replace("\r", "").replace("\n", "");
            String[] str86Array = str86.split("/");
            String AB = "AB";//D受益方银行
            String AB1 = "AB1";//D受益方银行
            String OB = "OB";//C受益方银行
            String OB1 = "OB1";//C受益方银行
            String BE = "BE";//D的受益方
            String BEN = "BEN";//D的受益方
            String BN = "BN";//D的受益方
            String BI = "BI";//D的受益方账户
            String BO = "BO";//C受益方姓名or帐号
            String BO1 = "BO1";//C受益方姓名
            String PY = "PY";//用途
            if ("1".equals(CdFlag)) {
                //受益人银行名称
                if (Contain(str86Array, AB1)) {
                    int index_AB1 = Arrays.asList(str86Array).indexOf(AB1);
                    if (index_AB1 + 1 <= str86Array.length)
                        tag86Map.put("RecAccBannk", str86Array[index_AB1 + 1]);
                } else {
                    if (Contain(str86Array, AB)) {
                        int index_AB = Arrays.asList(str86Array).indexOf(AB);
                        if (index_AB + 1 <= str86Array.length)
                            tag86Map.put("RecAccBannk", str86Array[index_AB + 1]);
                    }
                }
                //受益人名称
                if (Contain(str86Array, BE)) {
                    if (Contain(str86Array, BEN)) {
                        int index_BE = Arrays.asList(str86Array).indexOf(BE);
                        /*if (index_BE + 1 <= str86Array.length)
                            tag86Map.put("RecAccName", str86Array[index_BE + 1]);*/
                        if (qryHisTrans) {
                            tag86Map.put("RecAccName", getSubFieldValue("MT940", "86", str86Array, index_BE));
                        } else {
                            tag86Map.put("RecAccName", getSubFieldValue("MT942", "86", str86Array, index_BE));
                        }
                        int index_BEN = Arrays.asList(str86Array).indexOf(BEN);
                        /*if (index_BEN + 1 <= str86Array.length)
                            tag86Map.put("RecAccName", new StringBuffer(tag86Map.get("RecAccName")).append(" ").append(str86Array[index_BEN + 1]).toString());*/
                        if (qryHisTrans) {
                            tag86Map.put("RecAccName", new StringBuffer(tag86Map.get("RecAccName")).append(" ").append(getSubFieldValue("MT940", "86", str86Array, index_BEN)).toString());
                        } else {
                            tag86Map.put("RecAccName", new StringBuffer(tag86Map.get("RecAccName")).append(" ").append(getSubFieldValue("MT942", "86", str86Array, index_BEN)).toString());
                        }
                    } else {
                        int index_BE = Arrays.asList(str86Array).indexOf(BE);
                        /*if (index_BE + 1 <= str86Array.length)
                            tag86Map.put("RecAccName", str86Array[index_BE + 1]);*/
                        if (qryHisTrans) {
                            tag86Map.put("RecAccName", getSubFieldValue("MT940", "86", str86Array, index_BE));
                        } else {
                            tag86Map.put("RecAccName", getSubFieldValue("MT942", "86", str86Array, index_BE));
                        }
                    }
                } else if (Contain(str86Array, BN)) {
                    int index_BN = Arrays.asList(str86Array).indexOf(BN);
                    /*if (index_BN + 1 <= str86Array.length)
                        tag86Map.put("RecAccName", str86Array[index_BN + 1]);*/
                    if (qryHisTrans) {
                        tag86Map.put("RecAccName", getSubFieldValue("MT940", "86", str86Array, index_BN));
                    } else {
                        tag86Map.put("RecAccName", getSubFieldValue("MT942", "86", str86Array, index_BN));
                    }
                }
                //受益人帐号
                if (Contain(str86Array, BI)) {
                    int index_BI = Arrays.asList(str86Array).indexOf(BI);
                    if (index_BI + 1 <= str86Array.length)
                        tag86Map.put("RecAccNum", str86Array[index_BI + 1]);
                }
            } else if ("2".equals(CdFlag)) {
                //受益人银行名称
                if (Contain(str86Array, OB1)) {
                    int index_OB1 = Arrays.asList(str86Array).indexOf(OB1);
                    if (index_OB1 + 1 <= str86Array.length)
                        tag86Map.put("RecAccBannk", str86Array[index_OB1 + 1]);
                } else {
                    if (Contain(str86Array, OB)) {
                        int index_OB = Arrays.asList(str86Array).indexOf(OB);
                        if (index_OB + 1 <= str86Array.length)
                            tag86Map.put("RecAccBannk", str86Array[index_OB + 1]);
                    }
                }
                if (Contain(str86Array, BO1)) {
                    //受益人名称
                    int index_BO1 = Arrays.asList(str86Array).indexOf(BO1);
                    /*if (index_BO1 + 1 <= str86Array.length)
                        tag86Map.put("RecAccName", str86Array[index_BO1 + 1]);*/
                    if (qryHisTrans) {
                        tag86Map.put("RecAccName", getSubFieldValue("MT940", "86", str86Array, index_BO1));
                    } else {
                        tag86Map.put("RecAccName", getSubFieldValue("MT942", "86", str86Array, index_BO1));
                    }
                    //受益人帐号
                    if (Contain(str86Array, BO)) {
                        int index_BO = Arrays.asList(str86Array).indexOf(BO);
                        if (index_BO + 1 <= str86Array.length)
                            tag86Map.put("RecAccNum", str86Array[index_BO + 1]);
                    }
                } else {
                    //受益人名称
                    if (Contain(str86Array, BO)) {
                        int index_BO = Arrays.asList(str86Array).indexOf(BO);
                        /*if (index_BO + 1 <= str86Array.length)
                            tag86Map.put("RecAccName", str86Array[index_BO + 1]);*/
                        if (qryHisTrans) {
                            tag86Map.put("RecAccName", getSubFieldValue("MT940", "86", str86Array, index_BO));
                        } else {
                            tag86Map.put("RecAccName", getSubFieldValue("MT942", "86", str86Array, index_BO));
                        }
                    }
                }
            }

            if (Contain(str86Array, PY)) {
                int index_PY = Arrays.asList(str86Array).indexOf(PY);
                /*if (index_PY + 1 <= str86Array.length)
                    tag86Map.put("Usage",str86Array[index_PY + 1]);*/
                if (qryHisTrans) {
                    tag86Map.put("Usage", getSubFieldValue("MT940", "86", str86Array, index_PY));
                } else {
                    tag86Map.put("Usage", getSubFieldValue("MT942", "86", str86Array, index_PY));
                }
            }
        }
        return tag86Map;
    }

    protected Map<String, String> resolveTag86(String str86) {
        Map<String, String> tag86Map = new HashMap<String, String>();
        Map<String, String> params = (Map<String, String>) JSON.parse(str86);
        tag86Map.put("RecAccBannk", params.get("opBankName"));
        tag86Map.put("RecAccName", params.get("opAccountName"));
        tag86Map.put("RecAccNum", params.get("opAccountId"));
        tag86Map.put("Usage", params.get("paymentDetails"));
        tag86Map.put("Originator", params.get("reference"));
        tag86Map.put("opIdentifyCode", params.get("opIdentifyCode"));
        return tag86Map;
    }

    private static String MT940TAG86SUBFIELDNAME = ",1F,2F,3F,4F,AB,AB1,AB2,AB3,AB4,AC,ACCT,ACDT,AD,ALCR,AM,AO,AR,AS,BA,BB,BBLR,BC,BCN,BE,BI,BLCR,BN,BN1,BN2,BN3,BN4,BNC,BNREF,BO,BO1,BO2,BO3,BO4,BO5,BOC,BR,BTC,BTN,BVFD,BVOD,BVPD,BVTD,CA,CBK,CBK1,CBK2,CBK3,CBK4,CBLR,CD,CDT,CE,CF,CH,CHG2,CHGS,CHN,CI,CM,CN,CO,CPC,CQ,CR,CT,CY,DC,DSEQ,DV,ED,EI,EI1,ER,FCT,FXCM,FXREF,IB,IB1,IB2,IB3,IB4,IBK,IBK1,IBK2,IBK3,IBK4,IP,IR,IREF,LOC,LOCI,MREF,NA,NAC,NAP,NAT,NM,NN,NND,NSD,OA,OB,OB1,OB2,OB3,OB4,OCMT,OK,OK1,OK2,OK3,OK4,PAYSUP,PC,PDC,PI,PN,POD,PREF,PRREF,PY,PY01,PY02,PY03,PY04,PY05,PY06,PY07,PY08,PY09,PY10,PY11,PY12,PY13,PY14,PY15,PY16,PY17,PY18,PY19,PY20,PY21,PY22,PY23,PY24,PY25,PY26,PY27,PY28,PY29,PY30,PY31,PY32,PY33,PY34,PY35,PY36,PY37,PY38,PY39,PY40,PYD,PYO,RD,REF,REGC,RF,RI,RM,RMREF,ROC,RTDES,SCID,SK,SN,SR,ST,TAX,TC,TCOUNT,TD,TE,TT,TX,UAMR,UASP,UB,UBC,UIP,UN,UR,URC,WR,WT,PT,PO,";

    private static String MT942TAG86SUBFIELDNAME = ",1F,2F,3F,4F,AB,AB1,AB2,AB3,AB4,AC,ACCT,AD,ALCR,AM,AO,AS,BA,BB,BBLR,BC,BCN,BE,BEN,BI,BLCR,BN,BN1,BN2,BN3,BN4,BNC,BNREF,BO,BO1,BO2,BO3,BO4,BOC,BR,BVOD,BVPD,BVFD,BVTD,CA,CBK,CBK1,CBK2,CBK3,CBK4,CBLR,CD,CE,CF,CH,CHGS,CI,CM,CN,CO,CQ,CR,CT,CY,DA,DC,DV,ED,EI,EI1,EI2,ER,IB,IB1,IB2,IB3,IB4,IBK,IBK1,IBK2,IBK3,IBK4,IN,IP,IR,IREF,LOC,LT,NA,NAC,NAP,NN,NND,NSD,NT,OA,OB,OB1,OB2,OB3,OB4,OCMT,OK,OK1,OK2,OK3,OK4,PG,PI,PO,PREF,PRREF,PY,PY,PY01,PY02,PY03,PY04,PY05,PY06,PY07,PY08,PY09,PY10,PY11,PY12,PY13,PY14,PY15,PY16,PY17,PY18,PY19,PY20,PY21,PY22,PY23,PY24,PY25,PY26,PY27,PY28,PY29,PY30,PY31,PY32,PY33,PY34,PY35,PY36,PY37,PY38,PY39,PY40,PYD,PYO,REF,REGC,RF,RI,RM,RMREF,ROC,SK,SN,SR,ST,TAX,TC,TD,TE,TT,TX,UAHMR,UAHSP,UBC,UIP,UR,URC,UN,WR,WT,PT,PO,";

    private static String getSubFieldValue(String fileType, String tagName, String[] tagArray, int subIndex) {
        StringBuilder fieldValue = new StringBuilder();
        String compareFlag = "";
        if ("MT940".equals(fileType) && "86".equals(tagName)) {
            compareFlag = MT940TAG86SUBFIELDNAME;
        } else if ("MT942".equals(fileType) && "86".equals(tagName)) {
            compareFlag = MT942TAG86SUBFIELDNAME;
        }

        int addCount = 1;
        if (StringHelper.hasAnyChar(compareFlag)) {
            int totalCount = tagArray.length;
            for (int i = subIndex + 1; i < totalCount; i++) {
                String indexValue = tagArray[i];
                if (compareFlag.contains("," + indexValue + ",")) {
                    break;
                } else {
                    if (addCount > 1) {
                        fieldValue.append("/");
                    }
                    fieldValue.append(indexValue);
                    addCount++;
                }
            }
        }
        return fieldValue.toString();
    }

    private boolean Contain(String[] arr, String targetValue) {
        return Arrays.asList(arr).contains(targetValue);
    }
}
